/*
 * This file is part of "Deathwatch Ammo Counter for Android".
 *
 * "Deathwatch Ammo Counter for Android" is free software: you can redistribute
 * it and/or modify it under the terms of the GNU General Public License as 
 * published by the Free Software Foundation, either version 3 of the License, 
 * or (at your option) any later version.
 *
 * "Deathwatch Ammo Counter for Android" is distributed in the hope that it 
 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General 
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with "Deathwatch Ammo Counter for Android".  
 * If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package com.TikiiTorch.Deathwatch.AmmoCounter.file;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import android.util.Log;

import com.TikiiTorch.Deathwatch.AmmoCounter.AmmoLoad;
import com.TikiiTorch.Deathwatch.AmmoCounter.Ammunition;
import com.TikiiTorch.Deathwatch.AmmoCounter.C;
import com.TikiiTorch.Deathwatch.AmmoCounter.SpaceMarine;
import com.TikiiTorch.Deathwatch.AmmoCounter.Weapon;

public class SpaceMarineHandler extends DefaultHandler {

	SpaceMarine marine;

	Weapon weapon;

	Ammunition ammo;

	String ammoName;
	String ammoEffect;
	int inClip;
	int inBag;

	private boolean bCharacter = false;

	private boolean bWeapon = false;
	private boolean bWeapName = false;
	private boolean bWeapRof = false;
	private boolean bWeapType = false;
	private boolean bWeapClip = false;

	private boolean bAmmoSupply = false;
	private boolean bAmmoLoad = false;
	private boolean bEffect = false;
	private boolean bInClip = false;
	private boolean bInBag = false;

	public SpaceMarineHandler() {

	}

	@Override
	public void startDocument() throws SAXException {
		// some sort of setting up work
		marine = new SpaceMarine();
		weapon = null;
		ammo = null;
	}

	@Override
	public void endDocument() throws SAXException {
		// some sort of finishing up work
	}

	@Override
	public void startElement(String namespaceURI, String localName,
			String qName, Attributes atts) throws SAXException {
		if (qName.equalsIgnoreCase("character")) {
			// starting a character
			String name = atts.getValue("name");
			marine.setName(name);
			bCharacter = true;
		}
		if (bCharacter) {
			if (qName.equalsIgnoreCase("weapon")) {
				weapon = new Weapon();
				bWeapon = true;
			}

			if (bWeapon) { // are we inside a "weapon" element?
				if (qName.equalsIgnoreCase("weaponName")) {
					bWeapName = true;
				}
				if (qName.equalsIgnoreCase("rof")) {
					bWeapRof = true;
				}
				if (qName.equalsIgnoreCase("weaponType")) {
					bWeapType = true;
				}
				if (qName.equalsIgnoreCase("clipSize")) {
					bWeapClip = true;
				}
				if (qName.equalsIgnoreCase("ammoSupply")) {
					bAmmoSupply = true;
				}

				if (bAmmoSupply) { // are we inside an "ammoSupply" element?
					if (qName.equalsIgnoreCase("ammo")) {
						ammoName = atts.getValue("name");
						bAmmoLoad = true;
					}
					if (bAmmoLoad) { // are we inside an "ammo" element?
						if (qName.equalsIgnoreCase("effect")) {
							bEffect = true;
						}
						if (qName.equalsIgnoreCase("inClip")) {
							bInClip = true;
						}
						if (qName.equalsIgnoreCase("inBag")) {
							bInBag = true;
						}
					}
				}
			}
		}
	}

	@Override
	public void characters(char ch[], int start, int length) {
		if (bCharacter) { // are we inside a "character" element?

			if (bWeapon) { // are we inside a "weapon" element?

				if (bWeapName) {
					// parse for weapon name
					weapon.setName(new String(ch, start, length));
					bWeapName = false;
				}
				if (bWeapRof) {
					// parse for weapon rate of fire
					int[] weapRof = new int[3];
					String sRof = new String(ch, start, length);
					String[] rof = sRof.split(",");
					for (int i = 0; i < weapRof.length; i++)
						weapRof[i] = Integer.parseInt(rof[i]);
					weapon.setROF(weapRof);
					bWeapRof = false;
				}
				if (bWeapType) {
					weapon.setAmmoType(new String(ch, start, length));
					bWeapType = false;
				}
				if (bWeapClip) {
					weapon.setClipSize(Integer.parseInt(new String(ch, start,
							length)));
					bWeapClip = false;
				}
				if (bAmmoSupply) { // are we inside a "ammoSupply" element?

					if (bAmmoLoad) { // are we inside a "ammo" element?

						if (bEffect) {
							ammoEffect = new String(ch, start, length);
							bEffect = false;
						}

						if (bInClip) {
							inClip = Integer.parseInt(new String(ch, start,
									length));
							bInClip = false;
						}
						if (bInBag) {
							inBag = Integer.parseInt(new String(ch, start,
									length));
						}
					}

				}
			}
		}
	}

	/**
	 * Occurs when the parser reaches the end of an element
	 */
	@Override
	public void endElement(String namesaceURI, String localName, String qName)
			throws SAXException {
		if (qName.equalsIgnoreCase("character")) {
			// end of a character element
			bCharacter = false;
		}

		if (bCharacter) {

			if (qName.equalsIgnoreCase("weapon")) {
				// end of a weapon element
				marine.addWeapon(weapon);
				weapon = null;
				bWeapon = false;
			}

			if (bWeapon) {
				if (qName.equalsIgnoreCase("weaponName")) {
					// end of a weaponName element
					bWeapName = false;
				}
				if (qName.equalsIgnoreCase("rof")) {
					// end of a rof element
					bWeapRof = false;
				}
				if (qName.equalsIgnoreCase("clipSize")) {
					// end of a clipSize element
					bWeapClip = false;
				}

				if (qName.equalsIgnoreCase("ammoSupply")) {
					// end of a ammoSupply element
					bAmmoSupply = false;
				}

				if (bAmmoSupply) {

					if (qName.equalsIgnoreCase("ammo")) {
						weapon.addAmmoLoad(new AmmoLoad(new Ammunition(
								ammoName, ammoEffect), inClip, inBag, weapon
								.getClipSize()));

						Log.d(C.TAG, "Loading Ammo: " + ammoName);

						bAmmoLoad = false;
					}

					if (bAmmoLoad) {

						if (qName.equalsIgnoreCase("effect")) {
							bEffect = false;
						}
						if (qName.equalsIgnoreCase("inClip")) {
							bInClip = false;
						}
						if (qName.equalsIgnoreCase("inBag")) {
							bInBag = false;
						}
					}
				}

			}
		}
	}

	public SpaceMarine getSpaceMarine() {
		while (bCharacter) {
			// wait for parsing to finish just in case
		}
		return marine;
	}

}
